//
//  Singleton.h
//  单例模式类
//
//  Created by 张世敏 on 16/6/10.
//  Copyright © 2016年 zhangshimin. All rights reserved.
//

/* Singleton_h */

// .h文件
/** 提供获取单例对象的方法 **/
#define Singleton_h(ClassName) +(instancetype)shared##ClassName;

// .m文件
#if __has_feature(objc_arc) // ARC环境
#define Singleton_m(ClassName) static id instance;  \
+(instancetype)shared##ClassName{                   \
                                                    \
    static dispatch_once_t onceToken;               \
    dispatch_once(&onceToken, ^{                    \
        instance = [[self alloc] init];             \
    });                                             \
                                                    \
    return instance;                                \
}                                                   \
                                                    \
                                                    \
/** 防止用户使用new或alloc或copy方式创建类的对象 **/         \
+(instancetype)allocWithZone:(struct _NSZone *)zone{    \
                                                        \
    static dispatch_once_t onceToken;                   \
    dispatch_once(&onceToken, ^{                        \
        instance = [super allocWithZone:zone];          \
    });                                                 \
                                                        \
    return instance;                                    \
}                                                       \
                                                        \
                                                        \
-(id)copyWithZone:(NSZone *)zone{                       \
                                                        \
    return instance;                                    \
}


#else // MRC环境
// .m文件
#define Singleton_m(ClassName) static id instance;      \
+(instancetype)shared##ClassName{                       \
                                                        \
static dispatch_once_t onceToken;                       \
dispatch_once(&onceToken, ^{                            \
instance = [[self alloc] init];                         \
});                                                     \
                                                        \
return instance;                                        \
}                                                       \
                                                        \
                                                        \
/** 防止用户使用new或alloc或copy方式创建类的对象 **/         \
+(instancetype)allocWithZone:(struct _NSZone *)zone{    \
                                                        \
static dispatch_once_t onceToken;                       \
dispatch_once(&onceToken, ^{                            \
instance = [super allocWithZone:zone];                  \
});                                                     \
                                                        \
return instance;                                        \
}                                                       \
                                                        \
                                                        \
-(id)copyWithZone:(NSZone *)zone{                       \
                                                        \
return instance;                                        \
}                                                       \
                                                        \
                                                        \
/** 兼容MRC下,防止release,autorelease,retain,retainCount释放或引用计数增加或减少 **/ \
-(oneway void)release{                                  \
                                                        \
}                                                       \
                                                        \
                                                        \
-(instancetype)autorelease{                             \
                                                        \
    return instance;                                    \
}                                                       \
                                                        \
                                                        \
-(instancetype)retain{                                  \
                                                        \
    return instance;                                    \
}                                                       \
                                                        \
                                                        \
-(NSUInteger)retainCount{                               \
                                                        \
    return 1;                                           \
}
#endif


/* Singleton_h */
